package com.itbac.j2cache.client;

import com.github.benmanes.caffeine.cache.Cache;
import com.itbac.j2cache.rabbitmq.constants.RedisQueueName;
import com.itbac.j2cache.rabbitmq.message.J2CacheNotice;
import com.itbac.j2cache.rabbitmq.producer.J2CacheNoticeProducer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @description 二级缓存实现类  Caffeine + Redis
 *
 * @author itbac
 * @email 1218585258@qq.com
 * @date 2020/6/17
 */
@Service
public class J2CacheCaffeineClient implements J2CacheClient {

    private static Logger logger = LoggerFactory.getLogger(J2CacheCaffeineClient.class);

    //MQ生产者
    @Autowired
    private J2CacheNoticeProducer j2CacheNoticeProducer;
    //redis 分布式缓存
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RedisQueueName redisQueueName;
    //本地缓存
    @Resource(name = "caffeinecache")
    private Cache<String,String> cache;


    @Override
    public String getValue(String key) {
        return cache.get(key,(s) ->{
            return (String) redisTemplate.opsForValue().get(s);
        });
    }

    @Override
    public void delKey(String key, boolean notice) {
        redisTemplate.delete(key);
        this.delLocalKey(key, notice);
    }
    @Override
    public void delLocalKey(String key, boolean notice) {
        //删除本地缓存
        cache.invalidate(key);
        logger.info("J2CacheCaffeineClient.delLocalKey:key:{},notice:{} ", key, notice);
        //发送通知
        if (notice) {
            J2CacheNotice j2CacheNotice = new J2CacheNotice()
                    //设置本地标识
                    .setQueueName(redisQueueName.getName())
                    //设置操作类型:0，删除指定key缓存， 1 清空所有本地缓存
                    .setOperator(0)
                    .setMsg("你好，需要删缓存key:" + key)
                    .setKeys(new String[]{key});
            j2CacheNoticeProducer.publish(j2CacheNotice);
        }
    }

    @Override
    public void delLocalKeys(List<String> keys, boolean notice) {
        cache.invalidateAll(keys);
        logger.info("J2CacheCaffeineClient.delLocalKey:key:{},notice:{} ", keys, notice);
        //发送通知
        if (notice) {
            J2CacheNotice j2CacheNotice = new J2CacheNotice()
                    //设置本地标识
                    .setQueueName(redisQueueName.getName())
                    //设置操作类型:0，删除指定key缓存， 1 清空所有本地缓存
                    .setOperator(0)
                    .setMsg("你好，需要删缓存keys:" + keys.toString())
                    .setKeys(keys.toArray(new String[keys.size()]));
            j2CacheNoticeProducer.publish(j2CacheNotice);
        }
    }

    @Override
    public void delLocalAll(boolean notice) {
        cache.invalidateAll();
        logger.info("J2CacheCaffeineClient.invalidateAll,notice:{} ", notice);
        //发送通知
        if (notice) {
            J2CacheNotice j2CacheNotice = new J2CacheNotice()
                    //设置本地标识
                    .setQueueName(redisQueueName.getName())
                    //设置操作类型:0，删除指定key缓存， 1 清空所有本地缓存
                    .setOperator(1)
                    .setMsg("你好,需要清空所有本地缓存");
            j2CacheNoticeProducer.publish(j2CacheNotice);
        }
    }

    @Override
    public void set(String key, String value) {
        redisTemplate.opsForValue().set(key, value);
    }

    @Override
    public void set(String key, String value, int expire) {
        //设置过期，单位： 秒
        redisTemplate.opsForValue().set(key, value, expire, TimeUnit.SECONDS);
    }
}
